; AVM2 Assembler
; kudos to Dream Scheme


; Die with error
(define (asm-error msg)
  (display msg)
  (newline)
  (exit))

; Emit
; FIXME --------------
(define (emit b)
  (display (integer->char b)))

; blah!
(define (too-large? n)
  #F)

; 
(define (byte n)
  (if (and (number? n) (too-large? n))
      (asm-error "Number too wide for byte!")
      (emit n)))

; --------------------

(define *output-file* "out.swf")

(define (dump-code code)
  (call-with-output-file *output-file*
    (lambda (p)
      (for-each (lambda (e) (write e p)) code))))



; --------------------

;(define op byte)

(define (op b) b)

(define ($u30 n) n)


; AVM2 ops

(define (%add) (op #xA0))
(define (%add_i) (op #xC5))
(define (%astype index) (op #x86))
(define (%astypelate) (op #x87))
(define (%bitand) (op #xA8))
(define (%bitnot) (op #x97))
(define (%bitor) (op #xA9))
(define (%bitxor) (op #xAA))
(define (%call arg_count) (op #x41))
(define (%callmethod index arg_count) (op #x43))
(define (%callproperty index arg_count) (op #x46))
(define (%callproplex index arg_count) (op #x4C))
(define (%callpropvoid index arg_count) (op #x4F))
(define (%callstatic index arg_count) (op #x44))
(define (%callsuper index arg_count) (op #x45))
(define (%callsupervoid index arg_count) (op #x4E))
(define (%checkfiler) (op #x78))
(define (%coerce index) (op #x80))
(define (%coerce_a) (op #x82))
(define (%coerce_s) (op #x85))
(define (%construct arg_count) (op #x42))
(define (%constructprop index arg_count) (op #x4A))
(define (%constructsuper arg_count) (op #x49))
(define (%convert_b) (op #x76))
(define (%convert_i) (op #x73))
(define (%convert_d) (op #x75))
(define (%convert_o) (op #x77))
(define (%convert_u) (op #x74))
(define (%convert_s) (op #x70))
(define (%debug debug_type index reg extra) (op #xEF))
(define (%debugfile index) (op #xF1))
(define (%debugline linenum) (op #xF0))
(define (%declocal index) (op #x94))
(define (%declocal_i index) (op #xC3))
(define (%decrement) (op #x93))
(define (%decrement_i) (op #xC1))
(define (%deleteproperty index) (op #x6A))
(define (%divide) (op #xA3))
(define (%dup) (op #x2A))
(define (%dxns index) (op #x06))
(define (%dxnslate) (op #x07))
(define (%equals) (op #xAB))
(define (%esc_xattr) (op #x72))
(define (%esc_xelem) (op #x71))
(define (%findproperty index) (op #x5E))
(define (%findpropstrict index) (op #x5D))
(define (%getdescendants index) (op #x59))
(define (%getglobalscope) (op #x64))
(define (%getglobalslot slotindex) (op #x6E))
(define (%getlex index) (op #x60))
(define (%getlocal index) (op #x62))
(define (%getlocal_0) (op #xD0))
(define (%getlocal_1) (op #xD1))
(define (%getlocal_2) (op #xD2))
(define (%getlocal_3) (op #xD3))
(define (%getproperty index) (op #x66))
(define (%getscopeobject index) (op #x65))
(define (%getslot slotindex) (op #x6C))
(define (%getsuper index) (op #x04))
(define (%greaterequals) (op #xAF))
(define (%greaterthan) (op #xAF)) ; ???? what is going on?
(define (%hasnext) (op #x1F))
(define (%hasnext2 object_reg index_reg) (op #x32))
(define (%ifeq offset) (op #x13))
(define (%iffalse offset) (op #x12))
(define (%ifge offset) (op #x18))
(define (%ifgt offset) (op #x17))
(define (%ifle offset) (op #x16))
(define (%iflt offset) (op #x15))
(define (%ifnge offset) (op #x0F))
(define (%ifngt offset) (op #x0E))
(define (%ifnle offset) (op #x0D))
(define (%ifnlt offset) (op #x0C))
(define (%ifne offset) (op #x14))
(define (%ifstricteq offset) (op #x19))
(define (%ifstrictne offset) (op #x1A))
(define (%iftrue offset) (op #x11))
(define (%in) (op #xB4))
(define (%inclocal index) (op #x92))
(define (%inclocal_i index) (op #xC2))
(define (%increment) (op #x91))
(define (%increment_i) (op #xC0))
(define (%initproperty index) (op #x68))
(define (%instanceof) (op #xB1))
(define (%istype index) (op #xB2))
(define (%istypelate) (op #xB3))
(define (%jump offset) (op #x10))
(define (%kill index) (op #x08))
(define (%label) (op #x09))
(define (%lessequals) (op #xAE))
(define (%lessthan) (op #xAD))
(define (%lookupswitch default_offset case_count case_offsets...) (op #x1B)) ; multi!
(define (%lshift) (op #xA5))
(define (%modulo) (op #xA4))
(define (%multiply) (op #xA2))
(define (%multiply_i) (op #xC7))
(define (%negate) (op #x90))
(define (%negate_i) (op #xC4))
(define (%newactivation) (op #x57))
(define (%newarray arg_count) (op #x56))
(define (%newcatch index) (op #x5A))
(define (%newclass index) (op #x58))
(define (%newfunction index) (op #x40))
(define (%newobject arg_count) (op #x55))
(define (%nextname) (op #x1E))
(define (%nextvalue) (op #x23))
(define (%nop) (op #x02))
(define (%not) (op #x96))
(define (%pop) (op #x29))
(define (%popscope) (op #x1D))
(define (%pushbyte byte_value) (op #x24))
(define (%pushdouble index) (op #x2F))
(define (%pushfalse) (op #x27))
(define (%pushint index) (op #x2D))
(define (%pushnamespace index) (op #x31))
(define (%pushnan) (op #x28))
(define (%pushnull) (op #x20))
(define (%pushscope) (op #x30))
(define (%pushshort value) (op #x25))
(define (%pushstring index) (op #x2C))
(define (%pushtrue) (op #x26))
(define (%pushuint index) (op #x2E))
(define (%pushundefined) (op #x21))
(define (%pushwith) (op #x1C))
(define (%returnvalue) (op #x48))
(define (%returnvoid) (op #x47))
(define (%rshift) (op #xA6))
(define (%setlocal index) (op #x63))
(define (%setlocal_0) (op #xD4))
(define (%setlocal_1) (op #xD5))
(define (%setlocal_2) (op #xD6))
(define (%setlocal_3) (op #xD7))
(define (%setglobalslot slotindex) (op #x6F))
(define (%setproperty index) (op #x61))
(define (%setslot slotindex) (op #x6D))
(define (%setsuper index) (op #x05))
(define (%strictequals) (op #xAC))
(define (%subtract) (op #xA1))
(define (%subtract_i) (op #xC6))
(define (%swap) (op #x2B))
(define (%throw) (op #x03))
(define (%typeof) (op #x95))
(define (%urshift) (op #xA7))
